package com.tianji.aigc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.aigc.entity.ChatSession;
import com.tianji.aigc.mapper.ChatSessionMapper;
import com.tianji.aigc.properties.SessionProperties;
import com.tianji.aigc.service.IChatSessionService;
import com.tianji.aigc.vo.ChatHistoryVO;
import com.tianji.aigc.vo.MessageVO;
import com.tianji.aigc.vo.SessionVO;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.utils.UserContext;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 对话session 服务实现类
 * </p>
 *
 * @author ljy
 * @since 2025-09-02
 */
@Service
public class ChatSessionServiceImpl extends ServiceImpl<ChatSessionMapper, ChatSession> implements IChatSessionService {

    @Autowired
    private SessionProperties sessionProperties;


    /**
     * 创建会话session
     *
     * @param num 热门问题的数量
     * @return 会话信息
     */
    @Override
    public SessionVO createSession(Integer num) {
        //1.生成会话ID
        String sessionId = IdUtil.fastSimpleUUID();

        //2.保存会话历史
        ChatSession chatSession = ChatSession.builder().sessionId(sessionId)
                .userId(UserContext.getUser()).build();
        this.save(chatSession);

        //3.随机取出3个热门问题
        List<SessionVO.Example> examples = sessionProperties.getExamples();
        Collections.shuffle(examples);

        //4.封装响应结果
        SessionVO sessionVO = SessionVO.builder()
                .sessionId(sessionId)
                .describe(sessionProperties.getDescribe())
                .examples(examples.stream().limit(num).toList())
                .build();

        return sessionVO;
    }

    @Override
    public List<SessionVO.Example> queryHot(Integer num) {
        //3.随机取出3个热门问题
        List<SessionVO.Example> examples = sessionProperties.getExamples();
        Collections.shuffle(examples);
        return examples.stream().limit(num).toList();
    }

    @Autowired
    private ChatMemory chatMemory;

    /**
     * 获取会话详情
     *
     * @param sessionId 会话ID
     * @return
     */
    @Override
    public List<MessageVO> messageList(String sessionId) {
        //判断是会话ID是否存在
        ChatSession chatSession = this.lambdaQuery().eq(ChatSession::getSessionId, sessionId).one();
        if (chatSession == null) {
            throw new BizIllegalException("会话不存在");
        }

        //获取历史1000条消息
        List<Message> messageList = chatMemory.get(UserContext.getUser() + ":" + sessionId, 1000);
        return messageList.stream()
                //只获取用户消息和助手消息
                .filter(m -> m.getMessageType().equals(MessageType.USER) || m.getMessageType().equals(MessageType.ASSISTANT))
                .map(m -> MessageVO.builder().type(m.getMessageType()).content(m.getText()).build()).toList();
    }

    /**
     * 更新历史对话标题
     * @param question
     * @param sessionId
     * @param userId
     */
    @Async
    @Override
    public void updateSessionTitle(String question, String sessionId, Long userId) {
        //1. 查询回话是否存在
        ChatSession chatSession = this.lambdaQuery()
                .eq(ChatSession::getSessionId, sessionId)
                .eq(ChatSession::getUserId, userId)
                .one();
        //2. 不存在抛出异常信息
        if (ObjUtil.isEmpty(chatSession)) {
            throw new RuntimeException("该对话信息不存在，无法进行修改!");
        }
        //3. 存在根据条件修改 标题存在则修改时间，标题不存在则添加标题
        this.lambdaUpdate()
                .eq(ChatSession::getSessionId, sessionId)
                .eq(ChatSession::getUserId, userId)
                .set(StrUtil.isNotBlank(chatSession.getTitle()),ChatSession::getUpdateTime, LocalDateTime.now())
                .set(StrUtil.isBlank(chatSession.getTitle()),ChatSession::getTitle,question)
                .update();
    }

    /**
     * 查询历史会话列表
     * @return
     */
    @Override
    public Map<String, List<ChatHistoryVO>> getChatHistoryList() {
        //1. 查询用户最近30条历史会话数据
        List<ChatSession> chatSessionList = this.lambdaQuery().eq(ChatSession::getUserId, UserContext.getUser())
                .orderByDesc(ChatSession::getUpdateTime)
                .last("limit 30")
                .list();
        if(CollUtil.isEmpty(chatSessionList)){
            return Map.of();
        }

        //2. 类型转换
        List<ChatHistoryVO> chatHistoryVOList = BeanUtil.copyToList(chatSessionList, ChatHistoryVO.class);

        //3. 根据日期分组
        Map<String, List<ChatHistoryVO>> chatHistoryVoListMap = CollStreamUtil.groupByKey(chatHistoryVOList, vo -> {
            long between = Math.abs(ChronoUnit.DAYS.between(vo.getUpdateTime().toLocalDate(), LocalDate.now()));
            if(between<=0) {
                return "当天";
            } else if(between<=30){
                return "最近30天";
            } else if(between<=365) {
                return "最近1年";
            } else {
                return "1年以上";
            }
        });
        return chatHistoryVoListMap;
    }
}
